'use strict';
/**
 * Created by FreezeSoul on 2017/7/17.
 */
define([
    "app/core/base",
    "app/core/util",
    "../commonMeta",
    "jquery",
    "underscore",
    'JSONParse',
    'loglevel',
    'jOdometer'
], function (Chart, Util, Meta, $, _, JSON, log) {

    //TODO:自定义组件属性
    var property = {
        config: "property",
        option: [
            {
                group: '基础',
                id: 'NumberFormat',
                name: '数字格式化',
                enable: false,
                type: 'text',
                value: "000.0",
                default: "000.0",
                link: 'counterStart',
                tooltip: '数字格式化，注意长度保证最大，否则数字不完整'
            },
            {
                group: '基础',
                id: 'FontStyle',
                name: '字体样式',
                enable: false,
                type: 'select',
                value: 'app/plugins/controls/common/counter/resource/numbers-0.png',
                default: 'app/plugins/controls/common/counter/resource/numbers-0.png',
                data: [{
                    value: 'app/plugins/controls/common/counter/resource/numbers-0.png',
                    text: '深灰色'
                }, {
                    value: 'app/plugins/controls/common/counter/resource/numbers-1.png',
                    text: '洋葱紫'
                }, {
                    value: 'app/plugins/controls/common/counter/resource/numbers-2.png',
                    text: '湖水绿'
                }, {
                    value: 'app/plugins/controls/common/counter/resource/numbers-3.png',
                    text: '天空蓝'
                }, {
                    value: 'app/plugins/controls/common/counter/resource/numbers-4.png',
                    text: '军绿色'
                }, {
                    value: 'app/plugins/controls/common/counter/resource/numbers-5.png',
                    text: '海蓝色'
                }, {
                    value: 'app/plugins/controls/common/counter/resource/numbers-6.png',
                    text: '烈焰红'
                }],
                link: 'numbersImage',
                tooltip: '文本边框样式'
            },
            {
                group: '基础',
                id: 'HoverAnimationList',
                name: '鼠标响应',
                enable: false,
                type: 'select',
                value: '',
                default: '',
                data: [{
                    value: '',
                    text: '无效果'
                }, {value: 'bounce', text: 'bounce'},
                    {value: 'flash', text: 'flash'},
                    {value: 'pulse', text: 'pulse'},
                    {value: 'rubberBand', text: 'rubberBand'},
                    {value: 'shake', text: 'shake'},
                    {value: 'headShake', text: 'headShake'},
                    {value: 'swing', text: 'swing'},
                    {value: 'tada', text: 'tada'},
                    {value: 'wobble', text: 'wobble'},
                    {value: 'jello', text: 'jello'},
                    {value: 'bounceIn', text: 'bounceIn'},
                    {value: 'bounceInDown', text: 'bounceInDown'},
                    {value: 'bounceInLeft', text: 'bounceInLeft'},
                    {value: 'bounceInRight', text: 'bounceInRight'},
                    {value: 'bounceInUp', text: 'bounceInUp'},
                    {value: 'bounceOut', text: 'bounceOut'},
                    {value: 'bounceOutDown', text: 'bounceOutDown'},
                    {value: 'bounceOutLeft', text: 'bounceOutLeft'},
                    {value: 'bounceOutRight', text: 'bounceOutRight'},
                    {value: 'bounceOutUp', text: 'bounceOutUp'},
                    {value: 'fadeIn', text: 'fadeIn'},
                    {value: 'fadeInDown', text: 'fadeInDown'},
                    {value: 'fadeInDownBig', text: 'fadeInDownBig'},
                    {value: 'fadeInLeft', text: 'fadeInLeft'},
                    {value: 'fadeInLeftBig', text: 'fadeInLeftBig'},
                    {value: 'fadeInRight', text: 'fadeInRight'},
                    {value: 'fadeInRightBig', text: 'fadeInRightBig'},
                    {value: 'fadeInUp', text: 'fadeInUp'},
                    {value: 'fadeInUpBig', text: 'fadeInUpBig'},
                    {value: 'fadeOut', text: 'fadeOut'},
                    {value: 'fadeOutDown', text: 'fadeOutDown'},
                    {value: 'fadeOutDownBig', text: 'fadeOutDownBig'},
                    {value: 'fadeOutLeft', text: 'fadeOutLeft'},
                    {value: 'fadeOutLeftBig', text: 'fadeOutLeftBig'},
                    {value: 'fadeOutRight', text: 'fadeOutRight'},
                    {value: 'fadeOutRightBig', text: 'fadeOutRightBig'},
                    {value: 'fadeOutUp', text: 'fadeOutUp'},
                    {value: 'fadeOutUpBig', text: 'fadeOutUpBig'},
                    {value: 'flipInX', text: 'flipInX'},
                    {value: 'flipInY', text: 'flipInY'},
                    {value: 'flipOutX', text: 'flipOutX'},
                    {value: 'flipOutY', text: 'flipOutY'},
                    {value: 'lightSpeedIn', text: 'lightSpeedIn'},
                    {value: 'lightSpeedOut', text: 'lightSpeedOut'},
                    {value: 'rotateIn', text: 'rotateIn'},
                    {value: 'rotateInDownLeft', text: 'rotateInDownLeft'},
                    {value: 'rotateInDownRight', text: 'rotateInDownRight'},
                    {value: 'rotateInUpLeft', text: 'rotateInUpLeft'},
                    {value: 'rotateInUpRight', text: 'rotateInUpRight'},
                    {value: 'rotateOut', text: 'rotateOut'},
                    {value: 'rotateOutDownLeft', text: 'rotateOutDownLeft'},
                    {value: 'rotateOutDownRight', text: 'rotateOutDownRight'},
                    {value: 'rotateOutUpLeft', text: 'rotateOutUpLeft'},
                    {value: 'rotateOutUpRight', text: 'rotateOutUpRight'},
                    {value: 'hinge', text: 'hinge'},
                    {value: 'jackInTheBox', text: 'jackInTheBox'},
                    {value: 'rollIn', text: 'rollIn'},
                    {value: 'rollOut', text: 'rollOut'},
                    {value: 'zoomIn', text: 'zoomIn'},
                    {value: 'zoomInDown', text: 'zoomInDown'},
                    {value: 'zoomInLeft', text: 'zoomInLeft'},
                    {value: 'zoomInRight', text: 'zoomInRight'},
                    {value: 'zoomInUp', text: 'zoomInUp'},
                    {value: 'zoomOut', text: 'zoomOut'},
                    {value: 'zoomOutDown', text: 'zoomOutDown'},
                    {value: 'zoomOutLeft', text: 'zoomOutLeft'},
                    {value: 'zoomOutRight', text: 'zoomOutRight'},
                    {value: 'zoomOutUp', text: 'zoomOutUp'},
                    {value: 'slideInDown', text: 'slideInDown'},
                    {value: 'slideInLeft', text: 'slideInLeft'},
                    {value: 'slideInRight', text: 'slideInRight'},
                    {value: 'slideInUp', text: 'slideInUp'},
                    {value: 'slideOutDown', text: 'slideOutDown'},
                    {value: 'slideOutLeft', text: 'slideOutLeft'},
                    {value: 'slideOutRight', text: 'slideOutRight'},
                    {value: 'slideOutUp', text: 'slideOutUp'}],
                link: 'hoverAnimation',
                tooltip: '鼠标响应动画'
            },
            {
                group: '绑定',
                id: 'BangDingData',
                name: '绑定数值',
                enable: false,
                type: 'textBinding',
                dataset: '',
                ctype: 'measure',
                column: {},
                tooltip: '数值绑定，绑定字段格式要求小于【数字格式化】长度'
            },
            {
                group: '绑定',
                id: 'FilterName',
                name: '过滤列名称',
                enable: false,
                type: 'text',
                value: '',
                default: '',
                link: 'filterName',
                tooltip: '绑定数据集，客户端过滤字段列名称'
            },
            {
                group: '绑定',
                id: 'FilterValue',
                name: '过滤列默认值',
                enable: false,
                type: 'text',
                value: '',
                default: '',
                link: 'filterValue',
                tooltip: '绑定数据集，客户端过滤字段默认值'
            }
        ].concat($.extend(true, [], Meta.commonProperties)),
        MapOption: function (option) {
            Util.linkOption(this.option, option);
        }
    };

    var counter = Chart.extend({
        constructor: function (layout) {
            this._layout = layout;
            this._element = null;
            this._lastdata = null;
            this._container = null;
            this._counter = null;
            this._counterValue = null;
            this._option = {
                Series: [],
                Events: [],
                Extend: $.extend(true, {}, property),
                Option: {
                    uuid: '',
                    class: '',
                    display: true,
                    counterStart: '000.0',
                    delayTime: 1000,
                    increment: 0.1,
                    speed: 500,
                    easing: 'swing',
                    numbersImage: 'app/plugins/controls/common/counter/resource/numbers-0.png',
                    heightNumber: 31,
                    widthNumber: 22,
                    offsetRight: 0,
                    spaceNumbers: 0,
                    widthDot: 10,
                    formatNumber: false,
                    hoverAnimation: "",
                    initScript: '',
                    disposeScript: ''
                }
            };
            /**
             jOdometer is a counter that works like an odometer: moving the numbers up like a wheel

             Usually we will need a "position: relative" and an "overflow: hidden" in the container element.

             Sample Configuration:
             $('.counter').jOdometer({increment: 3.17, counterStart:'0087.15', counterEnd:'0159.50', numbersImage: '/images/numbers.png', spaceNumbers: 2, offsetRight:5});

             Config Options:
             counterStart: Number we are starting with. To get a specific number of digits/decimals it have to be a string (e.g. '0005.50') // Default: '0000.00'
             counterEnd: The counter stop when reach this number. If it is the same as counterStart the odometer is static. False to don't stop never. // Default: false
             delayTime: Delay between each number change // Default: 1000
             increment: Number increment after each delayTime // Default: 0.01
             speed: Speed for the change number animation // Default: 500
             easing: Easing for the change number animation. Other than 'swing' or 'linear' must be provided by plugin // Default: 'swing'
             numbersImage: Image used for the numbers. You can use .psd provided // Default: '/images/numbers.png'
             heightNumber: The height that each number needs // Default: 31
             widthNumber: Width of the numbers' image // Default: 14
             offsetRight: Distance to the right // Default: 0
             spaceNumbers: Separation between the numbers' columns // Default: 0
             widthDot: Decimal dot's special width // Default: 10
             formatNumber: Whether to format the number with commas every 3 digits // Default: false

             We can override the defaults with:
             $.fn.jOdometer.defaults.spaceNumbers = 1;

             It returns an object used for counter manipulation. Available Functions:
             goToNumber(number): Updates the counter with the number given. Example:
             var counter = $('.counter').jOdometer({...});
             counter.goToNumber(100);
             **/
        },
        init: function (element) {
            try {
                this._container = element;
            } catch (e) {
                log.error(e);
            }
        },
        example: function () {
            try {
                this._element = this._render(this._option.Option);
            } catch (e) {
                log.error(e);
            }
        },
        _bindEvent: function () {
            var _this = this;
            if (!this._filterDataHandle) {
                this._filterDataHandle = function (params) {
                    _this.filterDataHandle.call(_this, params);
                };
            }
            this._layout.removeListener("filterData", this._filterDataHandle);
            this._layout.addListener("filterData", this._filterDataHandle);
        },
        filterDataHandle: function (params) {
            var _this = this;
            var flag = false;
            var filterColumn = _.findWhere(this._option.Extend.option, {name: '过滤列名称'});
            var filterValue = _.findWhere(this._option.Extend.option, {name: '过滤列默认值'});

            if (filterColumn && filterValue
                && filterColumn.enable && filterValue.enable
                && filterColumn.value !== "" && filterValue.value !== ""
            ) {
                for (var prop in params) {
                    if (!params.hasOwnProperty(prop)) continue;
                    if (filterColumn.value === prop) {
                        filterValue.value = params[prop];
                        flag = true;
                    }
                }
            }
            if (flag && _this._lastdata) {
                _this.setData(_this._lastdata);
            }
        },
        _render: function (option) {
            if (this.__isEditMode) {
                this._counter = null;
            }
            if (!this._counter) {
                var $element = $("<span style='width: 100%;overflow: hidden;display: inline-block;position: relative;'></span>");
                $element.css({"height": option.heightNumber + "px"});
                $(this._container).empty();
                $element.appendTo(this._container);
                var newOption = $.extend(true, {}, option);
                this._counter = $element.jOdometer(newOption);
                if (this._counterValue)
                    this._counter.goToNumber(this._counterValue);
            } else {
                if ($.isNumeric(this._counterValue))
                    this._counter.goToNumber(this._counterValue);
            }
            if (this._option.Option.hoverAnimation) {
                var _this = this;
                $element.hover(
                    function () {
                        if ($element.hasClass("animated")) return;
                        $element.addClass("animated " + _this._option.Option.hoverAnimation)
                            .one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function () {
                                $element.removeClass("animated " + _this._option.Option.hoverAnimation)
                            });
                    }, function () {
                    }
                );
            }
            //Util.setCommonMeta(this, this._container, this._option.Option);
            //Util.initChartLifeTime(this, this._container, this._option.Option);
            return $element;
        },
        _bindData: function (data) {
            var bindProperty = _.findWhere(this._option.Extend.option, {id: 'BangDingData'});
            var totalLength = (this._option.Option.increment + '').length;
            var rightLength = (this._option.Option.increment + '').indexOf('.');
            if (bindProperty && bindProperty.dataset) {
                var dataSetCode = bindProperty.dataset;
                var table = data[dataSetCode];
                table = this._filterTable(this._option.Extend.option, table);
                if (table && table.length > 0 && bindProperty.column) {
                    var row = table[0];
                    var columnName = bindProperty.column.ColumnName;
                    if (columnName) {
                        this._counterValue = parseFloat(row[columnName]).toFixed(totalLength - (rightLength + 1));
                    }
                }
            }
        },
        _filterTable: function (option, table) {
            var filterColumn = _.findWhere(option, {name: '过滤列名称'});
            var filterValue = _.findWhere(option, {name: '过滤列默认值'});

            if (table && filterColumn && filterValue
                && filterColumn.enable && filterValue.enable
                && filterColumn.value !== "" && filterValue.value !== ""
            ) {
                var tableCopy = _.map(table, _.clone);
                return _.filter(tableCopy, function (row) {
                    return row[filterColumn.value] === filterValue.value;
                });
            }
            return table;
        },
        _readProperty: function () {
            try {
                if (!this._option.Extend) return;
                Util.deepMapOption(property, this._option.Extend, this._option.Option);
            } catch (e) {
                log.error(e);
            }
        },
        setData: function (data) {
            try {
                this._lastdata = data;

                this._readProperty();

                if (data
                    && this._option.Binding
                    && this._option.Binding.length > 0
                    && this._option.Extend
                ) {
                    this._bindData(data);

                    this._readProperty();
                }
                this._element = this._render(this._option.Option);
                this._bindEvent();
            } catch (e) {
                log.error(e);
            }
        },
        setOption: function (option) {
            try {
                return this._option = $.extend(true, {}, option);
            } catch (e) {
                log.error(e);
            }
        },
        getOption: function () {
            try {
                this._readProperty();
            } catch (e) {
                log.error(e);
            }
            return this._option;
        },
        setTheme: function (theme) {
            try {
            } catch (e) {
                log.error(e);
            }
        },
        resize: function () {
            try {
            } catch (e) {
                log.error(e);
            }
        },
        showLoading: function () {
            try {
                if (this._layout && this._layout.showLoading) {
                    this._layout.showLoading(this);
                }
            } catch (e) {
                log.error(e);
            }
        },
        hideLoading: function () {
            try {
                if (this._layout && this._layout.hideLoading) {
                    this._layout.hideLoading(this);
                }
            } catch (e) {
                log.error(e);
            }
        },
        dispose: function () {
            try {
                $(this._element).off().remove();
                this._layout.removeListener("filterData", this._filterDataHandle);
                //Util.disposeChartLifeTime(this, this._container, this._option.Option);
            } catch (e) {
                log.error(e);
            }
        },
        getElement: function () {
            return this._element;
        },
        getChart: function () {
            return this._element;
        }

    });

    return {
        Chart: counter,
        Property: property
    };
});